<?php
namespace addons\upyunup\service;
use addons\upyunup\Upyunup;
use Curl\CurlHttpRequest;
use Upyun\Config;
use Upyun\Upyun;

class Provide
{
    //================================= 服务管理业务相关 ================= //
    /**
     * @Notes:获取token信息
     * @User: chenping
     * @email: 375129701@qq.com
     */
    protected function getToken($token="3dc6b2d1-6c2a-4f21-adb9-670c301716df")
    {
        $url = "https://api.upyun.com/oauth/tokens";
        $param = [];
        $res = (new CurlHttpRequest())->curlHttpGet($url,$param,[
            CURLOPT_HTTPHEADER  => ["Authorization: Bearer $token"],
            CURLOPT_HEADER      => false
        ]);
        return $res;
}

    /**
     * @Notes:创建token 并返回token
     * @User: chenping
     * @email: 375129701@qq.com
     */
    protected function createToken($tokenName='公用token')
    {
        $url = "https://api.upyun.com/oauth/tokens";
        $config = (new Upyunup())->getConfigs();
        $param = [
            "username" => $config['username'],
            "password" => $config['password'],
            "code"     => make_string(22),
            "name"     => $tokenName,
            "scope"    => "global"
        ];
        $res = (new CurlHttpRequest())->curlHttpPost($url,$param);
        return $res;
    }

    /**
     * @Notes:创建token
     * @User: chenping
     * @email: 375129701@qq.com
     */
    protected function deleteToken($tokenName)
    {
        $url = "https://api.upyun.com/oauth/tokens";
        $param = [
            "name"     => "获取token",
        ];
        $res = (new CurlHttpRequest())->curlHttpDelete($url,$param,[
            CURLOPT_HTTPHEADER  => ["Authorization: Bearer 3dc6b2d1-6c2a-4f21-adb9-670c301716df"],
            CURLOPT_HEADER      => false
        ]);
        return $res;
    }

    //================================== 服务管理业务相关【结束】 =================//

    //================================= 对象存储服务 ============================//
    /**
     * @Notes:存储签名认证
     * @User: chenping
     * @email: 375129701@qq.com
     * @param $key 账户
     * @param $secret 账户密码
     * @param $method 请求类型
     * @param $uri 请求路径
     * @param $date 请求日期
     * @param null $policy
     * @param null $md5
     * @return string
     */
    public static function storageSign($key, $secret, $method, $uri, $date, $policy=null, $md5=null)
    {
        $elems = array();
        foreach (array($method, $uri, $date, $policy, $md5) as $v)
        {
            if ($v)
            {
                $elems[] = $v;
            }
        }
        $value = implode('&', $elems);
        $sign = base64_encode(hash_hmac('sha1', $value, $secret, true));
        return 'UPYUN ' . $key . ':' . $sign;
    }

    /**
     * @Notes:上传文件
     * @User: chenping
     * @email: 375129701@qq.com
     * @return mixed|string
     */
    public static function upload($file, $filePath, $fileType = 'image', $param = null,$sdk =true)
    {
        /**
         * 文件信息
         */
        $fileInfo = "";
        if(file_exists($filePath))
        {
            $fileInfo = pathinfo($filePath);
        }else {
            //临时缓存文件目录
            $fileList = chunkUploadFile();
            if (is_object($fileList)) {
                $fileList = $fileList->getData();
                if (isset($fileList['filePath']) && file_exists($fileList['filePath'])) {
                    $fileInfo = pathinfo($fileList['filePath']);
                }
            }
        }
        $fileName      = $fileInfo['filename'];
        $file_basename = $fileInfo['basename'];
        $ext           = $fileInfo['extension'];
        $fileSize      = filesize($fileInfo['dirname'].DIRECTORY_SEPARATOR.$fileInfo['basename']);

        /**
         * 又拍云上传信息
         */
        $date     = gmdate('D, d M Y H:i:s \G\M\T');
        $method   = "PUT";
        $file     = str_replace("\\","/",$file);
        $filePath = $file?'/'.$file:"/".date("Ymd",time()).'/'.getMsecTime().'.'.$ext;
        $sysCong = get_option(request()->param('app').'_upload_setting');
        if(isset($sysCong['bucket']) and isset($sysCong['operator']) and  isset($sysCong['peratorPwd']))
        {
            $config   = $sysCong;
        }else{
            $config   = (new Upyunup())->getConfigs();
        }
        $uri      = "/".$config['bucket'].$filePath;
        $url      = "http://v0.api.upyun.com".$uri;

        if($sdk)
        {
            $serviceConfig = new Config($config['bucket'], $config['operator'], $config['peratorPwd']);
            $client = new Upyun($serviceConfig);
            $fh = fopen( $fileInfo['dirname'].DIRECTORY_SEPARATOR.$fileInfo['basename'], 'r');
            $res = $client->write("/".$filePath, $fh);
        }else{
            //签名认证
            //$sign = md5("$method&{$uri}&{$date}&{$fileSize}&".md5($config['peratorPwd']));
            $sign = Provide::storageSign($config['operator'],md5($config['peratorPwd']),$method,$uri,$date);
            //header头设置
            $headers = array(
                "Expect:",
                "Date: ".$date,
                //"Authorization: UpYun {$config['operator']}:".$sign
                "Authorization:".$sign,
                /* "X-Upyun-Multi-Disorder" => true,
                 "X-Upyun-Multi-Stage"    => "initiate",
                 "X-Upyun-Multi-Length"   => $fh,
                 "Content-Length" => $fileSize*/
            );
            $fh = fopen( $fileInfo['dirname'].DIRECTORY_SEPARATOR.$fileInfo['basename'], 'r');
            //选项配置
            $option = [
                CURLOPT_HTTPHEADER  => $headers,
                CURLOPT_HEADER  => false,
                CURLOPT_INFILE  => $fh,
                CURLOPT_TIMEOUT => 60,
                CURLOPT_INFILESIZE => $fileSize,
                CURLOPT_RETURNTRANSFER=>1
            ];
            $res = (new CurlHttpRequest())->curlHttpPut($url,[],$option);
        }
        if(!empty($res) or isset($res['x-upyun-content-type']))
        {
            //删除临时文件
            if (isset($fileList['filePath']) && file_exists($fileList['filePath'])) {
                unlink($fileList['filePath']);
            }
            $filePath = str_replace(["\\","//","/"],'/',$filePath);
            $data =  [
                'preview_url' => $config['host'].$filePath,
                'url'         => str_replace('\\','/',$filePath),
                'basename'    => $file_basename,
                'filename'    => $fileName,
                'keywords'    => $fileName,
                'filepath'    => str_replace('\\','/',$file)
            ];
            return $data;
        }else{
            return false;
        }
    }

   /* public static function upload($file, $filePath, $fileType = 'image', $param = null,$sdk =true)
    {
        $rootPath = $filePath;

        if(!isset($_FILES['file']['name']) && !isset($_FILES['upfile']['name'])) return false;
        $files =  pathinfo(isset($_FILES['file'])?$_FILES['file']['name']:$_FILES['upfile']['name']);
        $file_basename = $files['basename'];
        $file_name =isset($_FILES['file'])?$_FILES['file']['name']:$_FILES['upfile']['name'];
        //文件格式
        $ext = pathinfo(isset($_FILES['file'])?$_FILES['file']['name']:$_FILES['upfile']['name'])['extension'];

        //相关配置
        $config = (new Upyunup())->getConfigs();
        //请求日期
        $date = gmdate('D, d M Y H:i:s \G\M\T');
        //请求方式
        $method = "PUT";
        //文件路径
        $file = str_replace("\\","/",$file);
        $filePath = $file?'/'.$file:"/".date("Ymd",time()).'/'.getMsecTime().'.'.$ext;
        //文件大小
        $fileSize = isset($_FILES['file'])?$_FILES['file']['size']:filesize($rootPath);
        //$fileSize = isset($_FILES['file'])?$_FILES['file']['size']:$_FILES['upfile']['size'];
        //请求I地址
        $uri = "/".$config['bucket'].$filePath;
        //上传路径
        $url = "http://v0.api.upyun.com".$uri;
        //打开需要上传的文件

        //$fh = fopen( isset($_FILES['file'])?$_FILES['file']['tmp_name']:$_FILES['upfile']['tmp_name'], 'r');
        //使用官方提供的sdk 上传
        if($sdk)
        {
            $serviceConfig = new Config($config['bucket'], $config['operator'], $config['peratorPwd']);
            $serviceConfig->setUploadType('BLOCK_PARALLEL');
            $client = new Upyun($serviceConfig);//$_FILES['upfile']['tmp_name']
            $fh = fopen( isset($_FILES['file'])?$_FILES['file']['tmp_name']:$rootPath, 'r');
            $res = $client->write("/".$filePath, $fh);
        }else{
            //签名认证
            //$sign = md5("$method&{$uri}&{$date}&{$fileSize}&".md5($config['peratorPwd']));
            $sign = Provide::storageSign($config['operator'],md5($config['peratorPwd']),$method,$uri,$date);
            //header头设置
            $headers = array(
                "Expect:",
                "Date: ".$date,
                //"Authorization: UpYun {$config['operator']}:".$sign
                "Authorization:".$sign
            );
            $fh = fopen( isset($_FILES['file'])?$_FILES['file']['tmp_name']:$_FILES['upfile']['tmp_name'], 'r');
            //选项配置
            $option = [
                CURLOPT_HTTPHEADER  => $headers,
                CURLOPT_HEADER  => false,
                CURLOPT_INFILE  => $fh,
                CURLOPT_TIMEOUT => 60,
                CURLOPT_INFILESIZE => $fileSize,
                CURLOPT_RETURNTRANSFER=>1
            ];
            $res = (new CurlHttpRequest())->curlHttpPut($url,[],$option);
        }
        if(empty($res) or isset($res['x-upyun-content-type']))
        {
            $filePath = str_replace(["\\","//","/"],'/',$filePath);
            return [
                'preview_url' => $config['host'].$filePath,
                'url'         => str_replace('\\','/',$filePath),
                'basename'    => $file_basename,
                'filename'    => $file_name,
                'keywords'    => $files['filename'],
                'filepath'    => str_replace('\\','/',$file)
            ];
        }else{
            return false;
        }
    }*/
    /**
     * @Notes:下载文件地址
     * @User: chenping
     * @email: 375129701@qq.com
     * @param string $filePath 又拍云文件得绝对地址
     * @param bool $loca 是否保存到服务器
     * @return \think\response\Download
     */
    public static function downloadFile($filePath='',$loca=false)
    {
        $filePath = _get_image_preview_url($filePath);

        //解析url地址
        $url = parse_url($filePath);
        $file = basename($filePath);
        /**
         * 是否保存到服务器
         * loca == true
         */
        if($loca==true)
        {
            $filePath = $url['path'];
            //保存目录
            $dir = "public".DIRECTORY_SEPARATOR.'download'.dirname($filePath).DIRECTORY_SEPARATOR;
            $newFilePath = $dir.$file;
            //创建目录
            if(!is_dir($dir)) mkdir(iconv("UTF-8", "GBK", $dir),0777,true);
            //下载文件
            $config = (new Upyunup())->getConfigs();
            $serviceConfig = new Config($config['bucket'], $config['operator'], $config['peratorPwd']);
            $client = new Upyun($serviceConfig);
            $saveLocal = fopen($newFilePath, 'w');
            $client->read($filePath,$saveLocal);
        }

        $filePath = $url['path'];
        //下载文件
        $config = (new Upyunup())->getConfigs();
        $serviceConfig = new Config($config['bucket'], $config['operator'], $config['peratorPwd']);
        $client = new Upyun($serviceConfig);
        //$saveLocal = fopen($newFilePath, 'w');

        //文件内容描述
        header('Content-Description: File Transfer');
        //自动填充指定的文件名
        header('Content-Disposition: attachment; filename=' . $file);
        //文件内容描述
        header('Content-Description: File Transfer');
        //文件二进制
        header('Content-Type: application/octet-stream');
        //告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
        header('Content-Transfer-Encoding: binary');
        //缓存过期时间
        header('Expires: 0');
        //强制页面不缓存
        header('Cache-Control: must-revalidate, post-hceck=0, pre-check=0');
        header('Pragma: public');
        echo  $client->read($filePath);

        /**
         * 调取浏览器下载文件
         */
        //文件内容描述
        //header('Content-Description: File Transfer');
        //自动填充指定的文件名
        //header('Content-Disposition: attachment; filename=' . $file);
        //文件二进制
        //header('Content-Type: application/octet-stream');
        //告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
        //header('Content-Transfer-Encoding: binary');
        //缓存过期时间
        //header('Expires: 0');
        //强制页面不缓存
        //header('Cache-Control: must-revalidate, post-hceck=0, pre-check=0');
        //header('Pragma: public');
        //文件流
        //readfile($filePath);
    }
    //================================= 对象存储服务【结束】 ============================//

    /**
     * @Notes:获取文件地址预览地址
     * @User: chenping
     * @email: 375129701@qq.com
     * @param $file
     * @param $style
     */
    public static function getPreviewUrl($file, $style)
    {
        //相关配置
        $config = (new Upyunup())->getConfigs();
        $filePath = str_replace(["\\","//","/"],'/',$file);
        return $config['host'].DIRECTORY_SEPARATOR.$filePath;
    }


    /**
     * 获取云存储域名
     * @return mixed
     */
    public function getDomain()
    {
        $config = (new Upyunup())->getConfigs();
        return $config['host'];
    }

    /**
     * 获取图片地址
     * @param string $file
     * @param string $style
     * @return mixed
     */
    public function getImageUrl($file, $style = 'watermark')
    {
        $config = (new Upyunup())->getConfigs();
        $url = str_replace(["\\","//","/"],'/', $file);
        $url = $config['host']."/".$url;
      /*  if (!empty($style)) {
            $url = $filePath;
        }*/
        return $url;
    }

    /**
     * 获取文件相对上传目录路径
     * @param string $url
     * @return mixed
     */
    public function getFilePath($url)
    {
        $parsedUrl = parse_url($url);

        if (!empty($parsedUrl['path'])) {
            $url            = ltrim($parsedUrl['path'], '/\\');
            /*$config         = (new Upyunup())->getConfigs();
            $styleSeparator = $config['style_separator'];
            $styleSeparatorPosition = strpos($url, $styleSeparator);
            if ($styleSeparatorPosition !== false) {
                $url = substr($url, 0, strpos($url, $styleSeparator));
            }*/
        } else {
            $url = '';
        }
        return $url;
    }

    /**
     * 获取文件下载地址
     * @param string $file
     * @param int    $expires
     * @return mixed
     */
    public function getFileDownloadUrl($file, $expires = 3600)
    {

        return str_replace("\\","/",_get_image_preview_url($file));

        $filename = basename(_get_image_preview_url($file));
        //解析url地址
        $url = parse_url($file);
        /**
         * 是否保存到服务器
         * loca == true
         */
        $filePath = $url['path'];
        //下载文件
        $config = (new Upyunup())->getConfigs();
        $serviceConfig = new Config($config['bucket'], $config['operator'], $config['peratorPwd']);
        $client = new Upyun($serviceConfig);
        //$saveLocal = fopen($newFilePath, 'w');

        //文件内容描述
        header('Content-Description: File Transfer');
        //自动填充指定的文件名
        header('Content-Disposition: attachment; filename=' . $filename);
        //文件内容描述
        header('Content-Description: File Transfer');
        //自动填充指定的文件名
        header('Content-Disposition: attachment; filename=' . $filename);
        //文件二进制
        header('Content-Type: application/octet-stream');
        //告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
        header('Content-Transfer-Encoding: binary');
        //缓存过期时间
        header('Expires: 0');
        //强制页面不缓存
        header('Cache-Control: must-revalidate, post-hceck=0, pre-check=0');
        header('Pragma: public');
        echo  $client->read($filePath);

        /*   exit;
           //解析url地址
           $filename = basename(_get_image_preview_url($file));

           //文件流
           readfile(_get_image_preview_url($file));
           exit;*/
    }


}